package com.xgxx.hy.library.admin.library.service.impl;

import com.xgxx.hy.library.admin.common.core.domain.AjaxResult;
import com.xgxx.hy.library.admin.common.core.domain.entity.SysUser;
import com.xgxx.hy.library.admin.common.utils.DateUtils;
import com.xgxx.hy.library.admin.common.utils.spring.SpringUtils;
import com.xgxx.hy.library.admin.dingtalk.service.IDingtalkService;
import com.xgxx.hy.library.admin.library.domain.BookBorrow;
import com.xgxx.hy.library.admin.library.enums.BorrowIsOverdueStatus;
import com.xgxx.hy.library.admin.library.enums.BorrowRecordStatusEnum;
import com.xgxx.hy.library.admin.library.enums.BorrowStatusEnum;
import com.xgxx.hy.library.admin.library.mapper.BookBorrowMapper;
import com.xgxx.hy.library.admin.library.service.IBookBorrowRecordService;
import com.xgxx.hy.library.admin.library.service.IBookBorrowService;
import com.xgxx.hy.library.admin.library.service.IBookService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 图书借阅Service业务层处理
 *
 * @author zyc
 * @date 2021-10-20
 */
@Service
@AllArgsConstructor
public class BookBorrowServiceImpl implements IBookBorrowService {
    private BookBorrowMapper bookBorrowMapper;
    private IBookBorrowRecordService bookBorrowRecordService;
    @Autowired
    private IDingtalkService dingtalkService;

    /**
     * 查询图书借阅
     *
     * @param id 图书借阅主键
     * @return 图书借阅
     */
    @Override
    public BookBorrow selectBookBorrowById(Long id) {
        return bookBorrowMapper.selectBookBorrowById(id);
    }

    @Override
    public BookBorrow selectBookBorrowByUser(BookBorrow bookBorrow) {
        return bookBorrowMapper.selectBookBorrowByUser(bookBorrow);
    }

    /**
     * 查询图书借阅列表
     *
     * @param bookBorrow 图书借阅
     * @return 图书借阅
     */
    @Override
    public List<BookBorrow> selectBookBorrowList(BookBorrow bookBorrow) {
        List<BookBorrow> list = bookBorrowMapper.selectBookBorrowList(bookBorrow);
        list.forEach(e -> {
            e.setBook(SpringUtils.getBean(BookServiceImpl.class).selectBookByCode(e.getBookCode()));
            e.setSysUser(SpringUtils.getBean(BookServiceImpl.class).getUserInfo(e.getBorrowUser()));
            e.setBorrowStatusStr(BorrowStatusEnum.getValue(e.getBorrowStatus()));
            if (this.isOverdue(e, DateUtils.getNowDate())) {
                e.setBorrowIsOverdue(1);
            }
        });
        return list;

    }

    /**
     * 新增图书借阅
     *
     * @param bookBorrow 图书借阅
     * @return 结果
     */
    @Override
    public int insertBookBorrow(BookBorrow bookBorrow) {
        return bookBorrowMapper.insertBookBorrow(bookBorrow);
    }

    /**
     * 修改图书借阅
     *
     * @param bookBorrow 图书借阅
     * @return 结果
     */
    @Override
    public int updateBookBorrow(BookBorrow bookBorrow) {
        return bookBorrowMapper.updateBookBorrow(bookBorrow);
    }

    /**
     * 批量删除图书借阅
     *
     * @param ids 需要删除的图书借阅主键
     * @return 结果
     */
    @Override
    public int deleteBookBorrowByIds(Long[] ids) {
        return bookBorrowMapper.deleteBookBorrowByIds(ids);
    }

    /**
     * 删除图书借阅信息
     *
     * @param id 图书借阅主键
     * @return 结果
     */
    @Override
    public int deleteBookBorrowById(Long id) {
        return bookBorrowMapper.deleteBookBorrowById(id);
    }

    @Override
    public AjaxResult bookBorrow(BookBorrow bookBorrow) {
        if (StringUtils.isBlank(bookBorrow.getBookCode()) || StringUtils.isBlank(bookBorrow.getBorrowUser())) {
            return AjaxResult.error("书籍编码和借书人必填");
        }
        BookBorrow bookBorrowQuery = new BookBorrow();
        bookBorrowQuery.setBorrowUser(bookBorrow.getBorrowUser());
        bookBorrowQuery.setBorrowStatus(BorrowStatusEnum.BORROW.getCode());
        List<BookBorrow> list = this.selectBookBorrowList(bookBorrowQuery);
        if (list.size() > 1) {
            return AjaxResult.error("在借数量已达到2本，无法借阅");
        }
        Date now = DateUtils.getNowDate();
        bookBorrow.setBorrowStartTime(now);
        bookBorrow.setBorrowAgain(0);
        bookBorrow.setBorrowStatus(BorrowStatusEnum.BORROW.getCode());
        this.insertBookBorrow(bookBorrow);
        bookBorrowRecordService.addBookBorrowRecord(bookBorrow.getBookCode(), bookBorrow.getBorrowUser(), now, BorrowRecordStatusEnum.BORROW.getCode());
        return AjaxResult.success();
    }

    @Override
    public AjaxResult bookBorrowAgain(BookBorrow bookBorrowParam) {
        bookBorrowParam.setBorrowStatus(BorrowStatusEnum.BORROW.getCode());
        BookBorrow bookBorrow = this.selectBookBorrowByUser(bookBorrowParam);
        if (null == bookBorrow) {
            return AjaxResult.error("图书非在借状态，无法续借");
        }
        Date now = DateUtils.getNowDate();
        // 计算是否逾期
        boolean isOverdue = this.isOverdue(bookBorrow, now);
        if (isOverdue) {
            return AjaxResult.error("借书已逾期，无法续借，请尽快还书");
        }
        bookBorrow.setBorrowAgain(1);
        bookBorrow.setBorrowAgainTime(now);
        this.updateBookBorrow(bookBorrow);
        bookBorrowRecordService.addBookBorrowRecord(bookBorrow.getBookCode(), bookBorrow.getBorrowUser(), now, BorrowRecordStatusEnum.AGAIN.getCode());
        return AjaxResult.success();
    }

    @Override
    public AjaxResult bookBorrowBack(BookBorrow bookBorrowParam) {
        bookBorrowParam.setBorrowStatus(BorrowStatusEnum.BORROW.getCode());
        BookBorrow bookBorrow = this.selectBookBorrowByUser(bookBorrowParam);
        if (null == bookBorrow) {
            return AjaxResult.error("图书非在借状态，无法归还");
        }
        Date now = DateUtils.getNowDate();
        bookBorrow.setBorrowStatus(BorrowStatusEnum.BACK.getCode());
        bookBorrow.setBorrowFinishTime(now);
        // 计算是否逾期
        if (this.isOverdue(bookBorrow, now)) {
            bookBorrow.setBorrowIsOverdue(1);
        }
        this.updateBookBorrow(bookBorrow);
        bookBorrowRecordService.addBookBorrowRecord(bookBorrow.getBookCode(), bookBorrow.getBorrowUser(), now, BorrowRecordStatusEnum.BACK.getCode());
        return AjaxResult.success();
    }

    @Override
    public AjaxResult bookMiss(BookBorrow bookBorrowParam) {
        bookBorrowParam.setBorrowStatus(BorrowStatusEnum.BORROW.getCode());
        BookBorrow bookBorrow = this.selectBookBorrowByUser(bookBorrowParam);
        if (null == bookBorrow) {
            return AjaxResult.error("图书非在借状态，无法挂失");
        }
        Date now = DateUtils.getNowDate();
        bookBorrow.setBorrowStatus(BorrowStatusEnum.MISS.getCode());
        bookBorrow.setBorrowFinishTime(now);
        // 计算是否逾期
        if (this.isOverdue(bookBorrow, now)) {
            bookBorrow.setBorrowIsOverdue(1);
        }
        this.updateBookBorrow(bookBorrow);
        bookBorrowRecordService.addBookBorrowRecord(bookBorrow.getBookCode(), bookBorrow.getBorrowUser(), now, BorrowRecordStatusEnum.MISS.getCode());
        return AjaxResult.success();
    }

    @Override
    public AjaxResult bookMissBack(BookBorrow bookBorrowParam) {
        Date now = DateUtils.getNowDate();
        bookBorrowRecordService.addBookBorrowRecord(bookBorrowParam.getBookCode(), bookBorrowParam.getBorrowUser(), now, BorrowRecordStatusEnum.MISS_BACK.getCode());
        return AjaxResult.success();
    }

    @Override
    public boolean isOverdue(BookBorrow bookBorrow, Date now) {
        Date start = bookBorrow.getBorrowAgain() == 1 ? bookBorrow.getBorrowAgainTime() : bookBorrow.getBorrowStartTime();
        Date finish = bookBorrow.getBorrowFinishTime() == null ? now : bookBorrow.getBorrowFinishTime();
        long days = this.getDatePoor(start, finish);
        bookBorrow.setBorrowDays(days);
        return days > 31;
    }

    public boolean isOverdueFive(BookBorrow bookBorrow, Date now) {
        Date start = bookBorrow.getBorrowAgain() == 1 ? bookBorrow.getBorrowAgainTime() : bookBorrow.getBorrowStartTime();
        Date finish = bookBorrow.getBorrowFinishTime() == null ? now : bookBorrow.getBorrowFinishTime();
        long days = this.getDatePoor(start, finish);
        bookBorrow.setBorrowDays(days);
        return (days > 26 && days < 31);
    }

    @Override
    public AjaxResult overdueAndBorrowAndBoticeList() {
        BookBorrow bookBorrowQuery = new BookBorrow();
        bookBorrowQuery.setBorrowStatus(BorrowStatusEnum.BORROW.getCode());
        List<BookBorrow> bookBorrowList = this.selectBookBorrowList(bookBorrowQuery);
        Date now = DateUtils.getNowDate();
        SimpleDateFormat formatYYYY = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        for (BookBorrow bookBorrow : bookBorrowList) {
            boolean flag = this.isOverdue(bookBorrow, now);
            if (flag) {
                //如果逾期，修改状态为“borrow_is_overdue”  1是逾期
                bookBorrow.setBorrowIsOverdue(BorrowIsOverdueStatus.YYQ.getCode());
                bookBorrowMapper.updateBookBorrow(bookBorrow);
            }
            //如果是五天以内，则钉钉通知
            boolean flagFive = this.isOverdueFive(bookBorrow, now);

            if (flagFive) {

                this.dingtalkService.sendMsg(bookBorrow.getBorrowUser().toString(), "您有书：" + bookBorrow.getBook().getBookName() + "，将逾期，请及时处理；若已归还，请忽略本条信息！  " + formatYYYY.format(DateUtils.getNowDate()));
            }
        }
        this.dingtalkService.sendMsg("18252101046", "您有书将逾期书本待归还，请及时处理；若已归还，请忽略本条信息！  " + formatYYYY.format(DateUtils.getNowDate()));
        return AjaxResult.success("操作成功！");
    }

    @Override
    public AjaxResult noticeBook(BookBorrow bookBorrow) {
        SimpleDateFormat formatYYYY = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        this.dingtalkService.sendMsg(bookBorrow.getBorrowUser().toString(), "您有书：" + bookBorrow.getBook().getBookName() + "，已逾期，请尽快归还!   " + formatYYYY.format(DateUtils.getNowDate()));
        return AjaxResult.success("操作成功！");
    }

    private long getDatePoor(Date start, Date finish) {
        return (finish.getTime() - start.getTime()) / (1000 * 24 * 60 * 60);
    }

    @Override
    public List<BookBorrow> overdueAndBorrowList() {
        BookBorrow bookBorrowQuery = new BookBorrow();
        bookBorrowQuery.setBorrowStatus(BorrowStatusEnum.BORROW.getCode());
        List<BookBorrow> bookBorrowList = this.selectBookBorrowList(bookBorrowQuery);
        Date now = DateUtils.getNowDate();
        return bookBorrowList.stream().filter(e -> this.isOverdue(e, now)).collect(Collectors.toList());
    }

    @Override
    public List<BookBorrow> overdueAndBackList() {
        BookBorrow bookBorrowQuery = new BookBorrow();
        bookBorrowQuery.setBorrowStatus(BorrowStatusEnum.BACK.getCode());
        bookBorrowQuery.setBorrowIsOverdue(1);
        return this.selectBookBorrowList(bookBorrowQuery);
    }
}
